﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Text.RegularExpressions;
using Sunyard.BPO.Database;

namespace ImageOCR
{
    /// <summary>
    /// 数据库匹配药品类
    /// </summary>
    class MatchMedicine
    {
        #region  获取与字符串符合的药品

        public static List<string> AllMedicinesFromDataBase = null;
        public static bool IsRefeshData = true;

        /// <summary>
        /// 获取与字符串符合的药品
        /// </summary>
        /// <param name="ocrMedicineValue">原始字符串</param>
        /// <param name="medicineName">匹配的药品</param>
        /// <param name="recognitionAccuracy">识别精度 </param>
        /// <returns>是否找到匹配药品</returns>
        public static bool SimilarMatching(string ocrMedicineValue, ref string medicineName, int recognitionAccuracy)
        {
            bool hasMatch = false;
            try
            {
                var retMedicine = new List<Medicine>();
                ocrMedicineValue = Regex.Replace(ocrMedicineValue, @"[[\s]|[\w]]", "");
                //设定20个
                //for (int i = 0; i < 20; i++)
                //{
                //    var ma = new Medicine();
                //    retMedicine.Add(ma);
                //}
                foreach (string strMedicine in AllMedicinesFromDataBase)
                {
                    int ret = levenshteinDistance(strMedicine, ocrMedicineValue) * 100 + strMedicine.Length;
                    // 超过35（含）不可信
                    if (ret >= recognitionAccuracy * 100 || ret < 0) { continue; }
                    //匹配值超过最后一个则替换

                    retMedicine.Add(new Medicine { MedicineName = strMedicine, LenLike = ret / 100 });

                    //if (ret / 100 < retMedicine[retMedicine.Count - 1].LenLike)
                    //{
                    //    retMedicine[retMedicine.Count - 1].MedicineName = strMedicine;
                    //    retMedicine[retMedicine.Count - 1].LenLike = ret / 100;
                    //}

                    sortMedicine(ref retMedicine);


                }
                if (retMedicine.Count > 0)
                {
                    hasMatch = true;
                    medicineName = retMedicine[0].MedicineName;
                }
            }
            catch (Exception ce)
            {
                LogService.Error(ce);
            }
            return hasMatch;
        }

        //冒泡排序
        private static void sortMedicine(ref List<Medicine> retMedicine)
        {
            for (int j = 0; j < retMedicine.Count - 1; j++)
            {
                for (int i = 0; i < retMedicine.Count - j - 1; i++)
                {
                    if (retMedicine[i].LenLike > retMedicine[i + 1].LenLike)
                    {
                        Medicine temp = retMedicine[i];
                        retMedicine[i] = retMedicine[i + 1];
                        retMedicine[i + 1] = temp;
                    }
                }
            }
        }
        //相似度算法
        private static int levenshteinDistance(string s, string t)
        {
            if (s == t) return 0;
            int m = t.Length; if (m == 0) return -1;
            int n = s.Length; if (n == 0) return 100;

            var matrix = new int[n + 1, m + 1];
            for (int i = 1; i <= n; i++) { matrix[i, 0] = 0; }
            for (int i = 1; i <= m; i++) { matrix[0, i] = 0; }

            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= m; j++)
                    if (s[i - 1] == t[j - 1]) matrix[i, j] = matrix[i - 1, j - 1] + 1;
                    else matrix[i, j] = matrix[i - 1, j] > matrix[i, j - 1] ? matrix[i - 1, j] : matrix[i, j - 1];

            int lcs = matrix[n, m];
            return ((n - lcs) + (m - lcs)) * 100 / (lcs == 0 ? 1 : lcs) / (lcs == 0 ? 1 : lcs);
        }

        //查询药品表
        public List<string> SelectMedicine()
        {
            var dbHelp = new DataBaseHelper(ConfigurationManager.AppSettings.Get("MANAGE"), ConfigurationManager.AppSettings.Get("ConnType"));
            Database db = dbHelp.GetDatabaseInstance();
            var allMedicine = new List<string>();
            IDataReader dr = null;
            try
            {
                const string _strSql = ("SELECT isnull(MName,'') as MName FROM MedicineInfo");
                DataParameter[] dp = { };
                dr = db.ExecuteDataReader(_strSql, false, ref dp);

                while (dr.Read())
                {
                    string mValue = dr["MName"].ToString();
                    if (!string.IsNullOrWhiteSpace(mValue))
                    {
                        allMedicine.Add(mValue);
                    }
                }
            }
            catch (Exception e)
            {
                LogService.Error(e);
            }
            finally
            {
                if (dr != null && !dr.IsClosed)
                    dr.Close();
            }
            return allMedicine;
        }

        //查询药品表是否已更新
        //public bool IsUpdateMedicine()
        //{
        //    var dbHelp = new DataBaseHelper(ConfigurationManager.AppSettings.Get("MANAGE"), ConfigurationManager.AppSettings.Get("ConnType"));
        //    Database db = dbHelp.GetDatabaseInstance();
        //    var isUpdate = false;
        //    IDataReader dr = null;
        //    try
        //    {
        //        const string _strSql = ("SELECT isnull(IsUpdate,0) as IsUpdate FROM MedicineInfoStatus");
        //        DataParameter[] dp = { };
        //        dr = db.ExecuteDataReader(_strSql, false, ref dp);

        //        if (dr.Read())
        //        {
        //            isUpdate =  Convert.ToBoolean(dr["IsUpdate"]);
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        LogService.Error(e);
        //    }
        //    finally
        //    {
        //        if (dr != null && !dr.IsClosed)
        //            dr.Close();
        //    }
        //    return isUpdate;
        //}

        #endregion
    }

    /// <summary>
    /// 数据库连接类
    /// </summary>
    class DataBaseHelper
    {
        public DataBaseHelper(string strConnection, string strType)
        {
            DatabaseType = strType;
            ConnectionString = strConnection;
        }
        /// <summary>
        /// 数据库类型
        /// </summary>
        private string DatabaseType { get; set; }

        /// <summary>
        /// 数据库连接串
        /// </summary>
        private string ConnectionString { get; set; }

        /// <summary>
        /// 构造数据库操作实例
        /// </summary>
        /// <returns></returns>
        public Database GetDatabaseInstance()
        {
            Database db = Database.CreateInstance(DatabaseType, ConnectionString);
            return db;
        }
    }
}
